<?php
error_reporting(E_ERROR);
include './func_v2.php';
$_SERVER['starttime'] = microtime(1);
$starttime            = explode(' ', $_SERVER['starttime']);
$_SERVER['time']      = $starttime[1];


ob_implicit_flush(1);
$sourceFolder = __DIR__ . '/code_test/';
$outputRoot = __DIR__ . '/encoded/';

// 递归处理文件夹及其子目录下的 PHP 文件的函数
function processFolder($sourceFolder, $outputRoot, $options) {
    // 再次检查源文件夹是否存在
    if (!is_dir($sourceFolder)) {
        echo "源文件夹 $sourceFolder 不存在，请检查路径。\n";
        return;
    }
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($sourceFolder, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );
    // 遍历迭代器中的每个项目
    foreach ($iterator as $item) {
        if ($item->isDir()) {
            // 如果当前项目是一个目录
            // 计算相对于源文件夹的相对路径
            $relativePath = substr($item->getPathname(), strlen($sourceFolder));
            // 构建对应的输出目录路径
            $outputDir = $outputRoot . $relativePath;
            // 检查输出目录是否存在，若不存在则创建
            if (!is_dir($outputDir)) {
                mkdir($outputDir, 0777, true);
            }
        } elseif ($item->isFile() && pathinfo($item, PATHINFO_EXTENSION) === 'php') {
            // 如果当前项目是一个 PHP 文件
            // 获取文件的完整路径
            $file = $item->getPathname();
            // 计算相对于源文件夹的相对路径
            $relativePath = substr($file, strlen($sourceFolder));
            // 构建对应的加密后文件的输出路径
            $target_file = $outputRoot . $relativePath;

            // 输出分隔线，用于区分不同文件的处理信息
            echo "\r\n", str_repeat("===", 5), "\r\n\r\n";
            // 调用 enphp_file 函数对文件进行加密处理
            enphp_file($file, $target_file, $options);
            // 记录加密操作的日志信息
            log::info('encoded', $target_file);

            // 初始化存储执行结果的数组
            $old_output = $output = array();
            // 执行加密后的文件，并将输出结果存储在 $output 数组中
            exec('php -d error_reporting=0 "' . $target_file . '"', $output);
            // 执行原始文件，并将输出结果存储在 $old_output 数组中
            exec('php -d error_reporting=0 "' . $file . '"', $old_output);

            // 将数组元素拼接成字符串
            $output = implode("\n", $output);
            $old_output = implode("\n", $old_output);
            // 将原始文件路径替换为加密后文件的路径，确保对比的一致性
            $old_output = strtr($old_output, [realpath($file) => realpath($target_file)]);

            // 比较加密前后文件的输出结果
            if ($old_output == $output) {
                // 如果结果相同，记录成功日志
                log::info('SUCCESS_TEST');
            } else {
                // 如果结果不同，记录失败日志，并输出加密前后的输出内容
                log::info('FAILURE_TEST');
                echo str_repeat('===', 5);
                echo "\r\nold=", trim($old_output), "\r\n";
                echo str_repeat('===', 5);
                echo "\r\nnew=", trim($output), "\r\n";
                // 终止当前循环
                break;
            }
        }
    }
}

// 调用 processFolder 函数处理源文件夹及其子目录下的 PHP 文件
processFolder($sourceFolder, $outputRoot, $options);
?>